( function ( $ , document , undefined ) {
    var  CLASS_PULL_TOP_POCKET  =  $ . className ( ' pull-top-pocket ' );
    var  CLASS_PULL_BOTTOM_POCKET  =  $ . className ( ' pull-bottom-pocket ' );
    var  CLASS_PULL  =  $ . className ( ' pull ' );
    var  CLASS_PULL_LOADING  =  $ . className ( ' pull-loading ' );
    var  CLASS_PULL_CAPTION  =  $ . className ( ' pull-caption ' );
    var  CLASS_PULL_CAPTION_DOWN  =  $ . className ( ' pull-caption-down ' );
    var  CLASS_PULL_CAPTION_REFRESH  =  $ . className ( ' pull-caption-refresh ' );
    var  CLASS_PULL_CAPTION_NOMORE  =  $ . className ( ' pull-caption-nomore ' );

    var  CLASS_ICON  =  $ . className ( ' icon ' );
    var  CLASS_SPINNER  =  $ . className ( ' spinner ' );
    var  CLASS_ICON_PULLDOWN  =  $ . className ( ' icon-pulldown ' );

    var  CLASS_BLOCK  =  $ . className ( ' block ' );
    var  CLASS_HIDDEN  =  $ . className ( ' hidden ' );
    var  CLASS_VISIBILITY  =  $ . className ( ' visibility ' );

    var  CLASS_LOADING_UP  =  CLASS_PULL_LOADING  +  '  '  +  CLASS_ICON  +  '  '  +  CLASS_ICON_PULLDOWN ;
    var  CLASS_LOADING_DOWN  =  CLASS_PULL_LOADING  +  '  '  +  CLASS_ICON  +  '  '  +  CLASS_ICON_PULLDOWN ;
    var  CLASS_LOADING  =  CLASS_PULL_LOADING  +  '  '  +  CLASS_ICON  +  '  '  +  CLASS_SPINNER ;

    var pocketHtml = [ ' <div class=" '  +  CLASS_PULL  +  ' "> ' , ' <div class="{icon}"></div> ' , ' <div class=" '  +  CLASS_PULL_CAPTION  +  ' ">{ contentrefresh}</div> ' , ' </div> ' ]. join ( ' ' );

    var PullRefresh = {
        init :  function ( element , options ) {
            this . _super (element, $ . extend ( true , {
                scrollY :  true ,
                scrollX :  false ,
                indicators :  true ,
                deceleration :  0.003 ,
                down : {
                    height :  50 ,
                    contentinit :  '下拉可以刷新' ,
                    contentdown :  '下拉可以刷新' ,
                    contentover :  '释放立即刷新' ,
                    contentrefresh :  '正在刷新... '
                },
                up : {
                    height :  50 ,
                    auto :  false ,
                    contentinit :  '上拉显示更多' ,
                    contentdown :  '上拉显示更多' ,
                    contentrefresh :  '正在加载... ' ,
                    contentnomore :  '没有更多数据了' ,
                    duration :  300
                }
            }, options));
        },
        _init :  function () {
            this . _super ();
            this . _initPocket ();
        },
        _initPulldownRefresh :  function () {
            this . pulldown  =  true ;
            if ( this . topPocket ) {
                this . pullPocket  =  this . topPocket ;
                this . pullPocket . classList . add ( CLASS_BLOCK );
                this . pullPocket . classList . add ( CLASS_VISIBILITY );
                this . pullCaption  =  this . topCaption ;
                this . pullLoading  =  this . topLoading ;
            }
        },
        _initPullupRefresh :  function () {
            this . pulldown  =  false ;
            if ( this . bottomPocket ) {
                this . pullPocket  =  this . bottomPocket ;
                this . pullPocket . classList . add ( CLASS_BLOCK );
                this . pullPocket . classList . add ( CLASS_VISIBILITY );
                this . pullCaption  =  this . bottomCaption ;
                this . pullLoading  =  this . bottomLoading ;
            }
        },
        _initPocket :  function () {
            var options =  this . options ;
            if ( options . down  &&  options . down . hasOwnProperty ( ' callback ' )) {
                this . topPocket  =  this . scroller . querySelector ( ' . '  +  CLASS_PULL_TOP_POCKET );
                if ( ! this . topPocket ) {
                    this . topPocket  =  this . _createPocket ( CLASS_PULL_TOP_POCKET , options . down , CLASS_LOADING_DOWN );
                    this . wrapper . insertBefore ( this . topPocket , this . wrapper . firstChild );
                }
                this . topLoading  =  this . topPocket . querySelector ( ' . '  +  CLASS_PULL_LOADING );
                this . topCaption  =  this . topPocket . querySelector ( ' . '  +  CLASS_PULL_CAPTION );
            }
            if ( options . up  &&  options . up . hasOwnProperty ( ' callback ' )) {
                this . bottomPocket  =  this . scroller . querySelector ( ' . '  +  CLASS_PULL_BOTTOM_POCKET );
                if ( ! this . bottomPocket ) {
                    this . bottomPocket  =  this . _createPocket ( CLASS_PULL_BOTTOM_POCKET , options . up , CLASS_LOADING );
                    this . scroller . appendChild ( this . bottomPocket );
                }
                this . bottomLoading  =  this . bottomPocket . querySelector ( ' . '  +  CLASS_PULL_LOADING );
                this . bottomCaption  =  this . bottomPocket . querySelector ( ' . '  +  CLASS_PULL_CAPTION );
                // TODO only for h5
                this . wrapper . addEventListener ( ' scrollbottom ' , this );
            }
        },
        _createPocket :  function ( clazz , options , iconClass ) {
            var pocket =  document . createElement ( ' div ' );
            pocket . className  = clazz;
            pocket . innerHTML  =  pocketHtml . replace ( ' {contentrefresh} ' , options . contentinit ). replace ( ' {icon} ' , iconClass);
            return pocket;
        },
        _resetPullDownLoading :  function () {
            var loading =  this . pullLoading ;
            if (loading) {
                this . pullCaption . innerHTML  =  this . options . down . contentdown ;
                loading . style . webkitTransition  =  " " ;
                loading . style . webkitTransform  =  " " ;
                loading . style . webkitAnimation  =  " " ;
                loading . className  =  CLASS_LOADING_DOWN ;
            }
        },
        _setCaptionClass :  function ( isPulldown , caption , title ) {
            if ( ! isPulldown) {
                switch (title) {
                    case  this . options . up . contentdown :
                        caption . className  =  CLASS_PULL_CAPTION  +  '  '  +  CLASS_PULL_CAPTION_DOWN ;
                        break ;
                    case  this . options . up . contentrefresh :
                        caption . className  =  CLASS_PULL_CAPTION  +  '  '  +  CLASS_PULL_CAPTION_REFRESH
                        break ;
                    case  this . options . up . contentnomore :
                        caption . className  =  CLASS_PULL_CAPTION  +  '  '  +  CLASS_PULL_CAPTION_NOMORE ;
                        break ;
                }
            }
        },
        _setCaption :  function ( title , reset ) {
            if ( this . loading ) {
                return ;
            }
            var options =  this . options ;
            var pocket =  this . pullPocket ;
            var caption =  this . pullCaption ;
            var loading =  this . pullLoading ;
            var isPulldown =  this . pulldown ;
            var self =  this ;
            if (pocket) {
                if (reset) {
                    setTimeout ( function () {
                        caption . innerHTML  =  self . lastTitle  = title;
                        if (isPulldown) {
                            loading . className  =  CLASS_LOADING_DOWN ;
                        } else {
                            self . _setCaptionClass ( false , caption, title);
                            loading . className  =  CLASS_LOADING ;
                        }
                        loading . style . webkitAnimation  =  " " ;
                        loading . style . webkitTransition  =  " " ;
                        loading . style . webkitTransform  =  " " ;
                    }, 100 );
                } else {
                    if (title !==  this . lastTitle ) {
                        caption . innerHTML  = title;
                        if (isPulldown) {
                            if (title ===  options . down . contentrefresh ) {
                                loading . className  =  CLASS_LOADING ;
                                loading . style . webkitAnimation  =  " spinner-spin 1s step-end infinite " ;
                            } else  if (title ===  options . down . contentover ) {
                                loading . className  =  CLASS_LOADING_UP ;
                                loading . style . webkitTransition  =  " -webkit-transform 0.3s ease-in " ;
                                loading . style . webkitTransform  =  " rotate(180deg) " ;
                            } else  if (title ===  options . down . contentdown ) {
                                loading . className  =  CLASS_LOADING_DOWN ;
                                loading . style . webkitTransition  =  " -webkit-transform 0.3s ease-in " ;
                                loading . style . webkitTransform  =  " rotate(0deg) " ;
                            }
                        } else {
                            if (title ===  options . up . contentrefresh ) {
                                loading . className  =  CLASS_LOADING  +  '  '  +  CLASS_VISIBILITY ;
                            } else {
                                loading . className  =  CLASS_LOADING  +  '  '  +  CLASS_HIDDEN ;
                            }
                            self . _setCaptionClass ( false , caption, title);
                        }
                        this . lastTitle  = title;
                    }
                }

            }
        }
    };
    $ . PullRefresh  = PullRefresh;
})(mui, document );